﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using UDS.Components;

namespace UDS.Entity
{
    /// <summary>
    /// Describe a single field in a flow style (表单).
    /// </summary>
    public class FlowStyleDescription
    {
        /// <summary>
        /// 职级
        /// </summary>
        public const string Caste = "caste";

        #region Properties

        public int StyleID
        {
            get;
            set;
        }

        /// <summary>
        /// Get or set the ID of this field.
        /// </summary>
        public int DescriptionID
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public string Description
        {
            get;
            set;
        }

        /// <summary>
        /// Indicate whether the field will be evaluated.
        /// </summary>
        public bool Judged
        {
            get;
            set;
        }

        public bool Multiline
        {
            get;
            set;
        }

        private int _height;
        public int Height
        {
            get { return Math.Max(10, _height); }
            set { _height = value; }
        }

        private int _width;
        public int Width
        {
            get { return Math.Max(10, _width); }
            set { _width = value; }
        }

        public int Position
        {
            get;
            set;
        }

        public string Example
        {
            get;
            set;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Get all the fields for the given style.
        /// </summary>
        public static IList<FlowStyleDescription> GetStyleDescription(int styleId)
        {
            if (styleId <= 0)
            {
                throw new ArgumentOutOfRangeException("styleId", "The style id must be greater than zero.");
            }

            var parameters = new[]
            {
                Database.MakeInParam("@StyleID", SqlDbType.Int, 4, styleId)
            };
            return GetFlowStyleDescriptionList("dbo.sproc_Flow_GetStyleDescription_V2", parameters);
        }

        public static IList<FlowStyleDescription> GetStyleDescriptionByFlow(int flowId)
        {
            return GetStyleDescriptionByFlow(flowId, false);
        }

        public static IList<FlowStyleDescription> GetStyleDescriptionByFlow(int flowId, bool judgedOnly)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@FlowID", SqlDbType.Int, 4, flowId),
                Database.MakeInParam("@JudgedOnly", SqlDbType.Bit, 1, judgedOnly)
            };
            return GetFlowStyleDescriptionList("dbo.sproc_Flow_GetStyleDescription_ByFlow_V2", parameters);
        }

        /// <summary>
        /// 添加自定义风格详细定义
        /// </summary>
        /// <param name="StyleID">表单ID</param>
        /// <param name="FieldName">绑定字段名</param>
        /// <param name="FieldDescription">字段意义</param>
        /// <param name="Judged">是否作为条件判断字段</param>
        /// <param name="MultiLine">是否多行</param>
        /// <param name="Height">控件高度</param>
        /// <param name="Width">控件宽</param>
        /// <param name="Position">控件在表单中的位置</param>
        /// <param name="Example">填表示例</param>
        public static int AddStyleDescription(int StyleID, string FieldName, string FieldDescription, bool Judged, bool MultiLine, int Height, int Width, int Position, string Example)
        {
            var mySQL = new Database();
            var parameters = new[]
            {
                Database.MakeInParam("@StyleID", SqlDbType.Int, 4, StyleID),
                Database.MakeInParam("@FieldName", SqlDbType.NVarChar, 100, FieldName),
                Database.MakeInParam("@FieldDescription", SqlDbType.NVarChar, 100, FieldDescription),
                Database.MakeInParam("@Judged", SqlDbType.Bit, 1, Judged),
                Database.MakeInParam("@MultiLine", SqlDbType.Bit, 1, MultiLine),
                Database.MakeInParam("@Height", SqlDbType.Int, 4, Height),
                Database.MakeInParam("@Width", SqlDbType.Int, 4, Width),
                Database.MakeInParam("@Position", SqlDbType.Int, 4, Position),
                Database.MakeInParam("@Example", SqlDbType.NVarChar, 100, Example)
            };

            return mySQL.RunProc("dbo.sproc_Flow_AddStyleDescription_V2", parameters);
        }

        /// <summary>
        /// 删除自定义风格表格详细定义，一行定义表示一个控件
        /// </summary>
        /// <param name="DescriptionID">风格详细定义ID</param>
        public static int DeleteStyleDescription(int DescriptionID)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@DescriptionID", SqlDbType.Int, 4, DescriptionID)
            };

            using (var db = new Database())
            {
                return db.RunProc("dbo.sproc_Flow_DeleteStyleDescription_V2", parameters);
            }
        }

        /// <summary>
        /// 修改自定义风格详细定义
        /// </summary>
        /// <param name="DescriptionID">风格详细定义ID</param>
        /// <param name="FieldDescription">字段意义</param>
        /// <param name="Judged">是否作为条件判断字段</param>
        /// <param name="MultiLine">是否多行</param>
        /// <param name="Height">控件高度</param>
        /// <param name="Width">控件宽</param>
        /// <param name="Position">控件在表单中的位置</param>
        /// <param name="Example">填表示例</param>
        public static int UpdateStyleDescription(int DescriptionID, string FieldDescription, bool Judged, bool MultiLine, int Height, int Width, int Position, string Example)
        {
            var parameters = new[]
            {
                Database.MakeInParam("@DescriptionID", SqlDbType.Int, 4, DescriptionID),
                // Database.MakeInParam("@FieldName", SqlDbType.NVarChar, 100, FieldName),
                Database.MakeInParam("@FieldDescription", SqlDbType.NVarChar, 100, FieldDescription),
                Database.MakeInParam("@Judged", SqlDbType.Bit, 1, Judged),
                Database.MakeInParam("@MultiLine", SqlDbType.Bit, 1, MultiLine),
                Database.MakeInParam("@Height", SqlDbType.Int, 4, Height),
                Database.MakeInParam("@Width", SqlDbType.Int, 4, Width),
                Database.MakeInParam("@Position", SqlDbType.Int, 4, Position),
                Database.MakeInParam("@Example", SqlDbType.NVarChar, 100, Example)
            };

            using (var db = new Database())
            {
                return db.RunProc("dbo.sproc_Flow_UpdateStyleDescription_V2", parameters);
            }
        }

        #endregion Methods

        #region Help methods

        private static FlowStyleDescription ReadFlowStyleDescription(IDataReader dr, int? styleId)
        {
            Debug.Assert(styleId == null || styleId.Value > 0);

            FlowStyleDescription d = new FlowStyleDescription();

            d.StyleID = (styleId == null) ? (int)dr["Style_ID"] : styleId.Value;
            d.DescriptionID = (int)dr["Description_ID"];
            d.Name = Convert.ToString(dr["Field_Name"]);
            d.Description = Convert.ToString(dr["Field_Description"]);
            d.Example = Convert.ToString(dr["Example"]);
            d.Judged = Utility.ReadBoolean(dr["Judged"], false);
            d.Multiline = Utility.ReadBoolean(dr["Multiline"], false);
            d.Width = Utility.ReadInt32(dr["Width"], 100);
            d.Height = Utility.ReadInt32(dr["Height"], 20);
            d.Position = Utility.ReadInt32(dr["Position"], 0);
            return d;
        }

        private static IList<FlowStyleDescription> GetFlowStyleDescriptionList(string spName, IEnumerable<SqlParameter> parameters)
        {
            var db = new Database();
            var list = new List<FlowStyleDescription>();
            using (var dr = db.RunDataReader(spName, parameters))
            {
                while (dr.Read())
                {
                    list.Add(ReadFlowStyleDescription(dr, null));
                }
            }

            return list;
        }

        #endregion
    }
}
